package com.zmn.oms.business.impl.report;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.dms.common.dto.coup.coupbatchstatistics.dio.CoupBatchStatisticsCoupUsedDIO;
import com.zmn.dms.common.dto.coup.coupbatchstatistics.dio.CoupBatchStatisticsMeasureDIO;
import com.zmn.dms.common.dto.coup.coupbatchstatistics.dro.CoupBatchStatisticsCoupUsedDRO;
import com.zmn.dms.common.dto.coup.coupbatchstatistics.dro.CoupBatchStatisticsDRO;
import com.zmn.dms.common.dto.coup.coupbatchstatistics.dro.CoupBatchStatisticsMeasureDRO;
import com.zmn.dms.dubbo.interfaces.coup.CoupBatchStatisticsRemoteService;
import com.zmn.oms.business.interfaces.report.CoupBatchStatisticsBService;
import com.zmn.oms.business.interfaces.report.ReportCoupAnalyseBService;
import com.zmn.oms.model.entity.report.CoupBatchFact;
import com.zmn.oms.model.entity.report.CoupBatchQuery;
import com.zmn.oms.model.entity.report.CoupUserWork;
import com.zmn.oms.model.entity.report.ReportCoupAnalyse;
import com.zmn.oms.services.interfaces.report.ReportCoupAnalyseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 优惠卷分析报表Bservice
 *
 * @author: HuangYongJie
 * @version: v1.0
 * @since: 2019/11/6 11:04
 **/
@Slf4j
@Service
public class ReportCoupAnalyseBServiceImpl implements ReportCoupAnalyseBService {

    @Reference(version = com.zmn.dms.dubbo.constant.DmsDubboConsts.INTERFACE_VERSION, check = false)
    private CoupBatchStatisticsRemoteService coupBatchStatisticsRemoteService;

    @Autowired
    private ReportCoupAnalyseService reportCoupAnalyseService;

    @Autowired(required = false)
    private CoupBatchStatisticsBService coupBatchStatisticsBService;

    private static final Integer DEFAULTNUM = Integer.valueOf(0);
    private static final Long DEFAULTATOMIC = Long.valueOf(0);

    private static final Integer DUBBO_SUCCESSE_STATUS = 200;

    /**
     * 同步优惠卷分析报表数据
     *
     * @return
     */
    @Override
    public String synReportCoupAnalyseData() {
        log.info("synReportCoupAnalyseData start!");
        List<ReportCoupAnalyse> dataList = listAlllBatchData();
        List<ReportCoupAnalyse> filterList = reportCoupAnalyseService.listCloseAndExpirData();
        if (dataList == null || dataList.isEmpty()) {
            log.info("数据为空，同步结束。");
            return "没有数据";
        }
        Map<Integer, ReportCoupAnalyse> filterMap = filterList.stream().collect(Collectors.toMap(ReportCoupAnalyse::getBatchId, obj -> obj));
        List<Integer> addList = Lists.newArrayList();
        dataList.forEach(obj -> {
            addList.add(obj.getBatchId());
        });
        List<CoupBatchStatisticsMeasureDRO> batchMeasureList = Lists.newArrayList();
        List<List<Integer>> lists = Lists.partition(addList, 50);
        for (List<Integer> list : lists) {
            CoupBatchStatisticsMeasureDIO var1 = new CoupBatchStatisticsMeasureDIO();
            var1.setBatchIds(list);
            ResponseDTO<List<CoupBatchStatisticsMeasureDRO>> responseDTO = coupBatchStatisticsRemoteService.getCoupMeasure(var1);
            log.info("coupItemStatisticsRemoteService.getCoupMeasure,list:{}", list);
            log.info("coupItemStatisticsRemoteService.getCoupMeasure,status:{}", responseDTO.getStatus());
            List<CoupBatchStatisticsMeasureDRO> batchMeasureData = responseDTO.getData();
            if (Objects.isNull(batchMeasureData)) {
                log.info("coupItemStatisticsRemoteService.getCoupMeasure is null data");
            } else {
                batchMeasureList.addAll(batchMeasureData);
            }
        }
        Map<Integer, CoupBatchStatisticsMeasureDRO> batchMeasureMap = batchMeasureList.stream().collect(Collectors.toMap(CoupBatchStatisticsMeasureDRO::getBatchId, obj -> obj));
        List<Integer> updateBatchIdList = Lists.newArrayList();
        List<ReportCoupAnalyse> modifyList = Lists.newArrayList();
        List<Integer> deleteBatchIdList = Lists.newArrayList();
        for (ReportCoupAnalyse obj : dataList) {
            CoupBatchStatisticsMeasureDRO tempDRO = batchMeasureMap.get(obj.getBatchId());
            if (tempDRO != null) {
                obj.setCoupGrantNum(tempDRO.getCoupItemIssueNumber());
                obj.setCoupReceiveNum(tempDRO.getCoupItemReceiveNumber());
                obj.setCoupUseNum(tempDRO.getCoupItemUsedNumber());
                obj.setUseCycle(tempDRO.getUsedTimeTotalNumber());
                obj.setCoupOrderNum(tempDRO.getCoupItemOrderNumber());
            } else {
                obj.setCoupGrantNum(DEFAULTNUM);
                obj.setCoupReceiveNum(DEFAULTNUM);
                obj.setCoupUseNum(DEFAULTNUM);
                obj.setUseCycle(DEFAULTNUM);
                obj.setCoupOrderNum(DEFAULTNUM);
            }
            //如果优惠劵使用量没有改变，则说明不需要同步
            if (tempDRO != null && filterMap.containsKey(tempDRO.getBatchId())) {
                if (filterMap.get(obj.getBatchId()).getCoupUseNum().equals(obj.getCoupUseNum()) && obj.getCoupUseNum().equals(0)) {
                    continue;
                }
                //如果改变了，则删除这条数据，重新同步
                deleteBatchIdList.add(obj.getBatchId());
                //reportCoupAnalyseService.deleteByKey(obj.getBatchId());
            }
            updateBatchIdList.add(obj.getBatchId());
            modifyList.add(obj);
        }
        log.debug("updateBatchIdListSize:{},updateBatchIdList:{}", updateBatchIdList.size(), updateBatchIdList);
        log.debug("modifyListSize:{},modifyList:{}", modifyList.size(), modifyList);
        log.debug("deleteBatchIdListSize:{},deleteBatchIdList:{}", deleteBatchIdList.size(), deleteBatchIdList);
        reportCoupAnalyseService.deleteBatchByKeyList(deleteBatchIdList);
        reportCoupAnalyseService.clearCloseAndExpirData();
        listCoupBatchFact(modifyList, updateBatchIdList);
        log.info("synReportCoupAnalyseData end!");
        return "同步成功";

    }

    /**
     * 获取所有的批次数据
     *
     * @return
     */
    @Override
    public List<ReportCoupAnalyse> listAlllBatchData() {
        ResponseDTO<List<CoupBatchStatisticsDRO>> responseDTO = coupBatchStatisticsRemoteService.getAllBatch();
        List<CoupBatchStatisticsDRO> dataList = responseDTO.getData();
        if (dataList == null || dataList.isEmpty()) {
            return Lists.newArrayList();
        }
        return dataList.stream().map(obj -> {
            ReportCoupAnalyse reportCoupAnalyse = new ReportCoupAnalyse();
            reportCoupAnalyse.setBatchId(obj.getBatchId());
            reportCoupAnalyse.setBatchName(obj.getBatchName());
            reportCoupAnalyse.setBatchCloseTime(obj.getCloseTime());
            reportCoupAnalyse.setBatchExpirationTime(obj.getExpireTime());
            return reportCoupAnalyse;
        }).collect(Collectors.toList());
    }

    /**
     * 获取度量订单
     *
     * @param batchIdList
     * @return
     */
    private void listCoupBatchFact(List<ReportCoupAnalyse> dataList, List<Integer> batchIdList) {
        if (batchIdList == null || batchIdList.isEmpty()) {
            log.info("report coup analyse data syn is null!");
            return;
        }
        Map<Integer, ReportCoupAnalyse> dataMap = dataList.stream().collect(Collectors.toMap(ReportCoupAnalyse::getBatchId, obj -> obj));
        if (dataMap == null) {
            dataMap = Maps.newHashMap();
        }
        for (Integer batchId : batchIdList) {
            getCoupBatchFact(dataMap.get(batchId), batchId);
        }
    }

    /**
     * 根据批次id拆线呢度量数据
     *
     * @param batchId
     * @return
     */
    @Override
    public void getCoupBatchFact(ReportCoupAnalyse reportCoupAnalyse, Integer batchId) {
        try {
            if (reportCoupAnalyse == null) {
                return;
            }
            CoupBatchStatisticsCoupUsedDIO paramDIO = new CoupBatchStatisticsCoupUsedDIO();
            paramDIO.setBatchId(batchId);
            ResponseDTO<List<CoupBatchStatisticsCoupUsedDRO>> responseDTO = coupBatchStatisticsRemoteService.getCoupUsed(paramDIO);

            List<CoupBatchStatisticsCoupUsedDRO> coupUsedDROList = responseDTO.getData();
            if (coupUsedDROList == null) {
                coupUsedDROList = Lists.newArrayList();
            }
            List<CoupUserWork> userWorkMaps = Lists.newArrayList();
            for (CoupBatchStatisticsCoupUsedDRO obj : coupUsedDROList) {
                CoupUserWork coupUserWork = new CoupUserWork();
                coupUserWork.setUserId(obj.getUserId());
                coupUserWork.setWorkId(obj.getOrderId());
                coupUserWork.setUseTime(obj.getUseTime());
                userWorkMaps.add(coupUserWork);
            }
            if (!userWorkMaps.isEmpty()) {
                CoupBatchQuery query = CoupBatchQuery.builder().batchID(batchId).userWorkMaps(userWorkMaps).build();
                CoupBatchFact coupBatchFact = coupBatchStatisticsBService.findCoupBatchFact(query);
                if (coupBatchFact != null) {
                    reportCoupAnalyse.setCoupNewOrderNum(coupBatchFact.getNewCount());
                    reportCoupAnalyse.setCoutRepeatOrderNum(coupBatchFact.getRepurchaseCount());
                    reportCoupAnalyse.setCoupPriceAmount(coupBatchFact.getDiscountAmount());
                    reportCoupAnalyse.setOrderOriginalPriceAmount(coupBatchFact.getOriginalAmount());
                } else {
                    reportCoupAnalyse.setCoupNewOrderNum(DEFAULTNUM);
                    reportCoupAnalyse.setCoutRepeatOrderNum(DEFAULTNUM);
                    reportCoupAnalyse.setCoupPriceAmount(DEFAULTATOMIC);
                    reportCoupAnalyse.setOrderOriginalPriceAmount(DEFAULTATOMIC);
                }
            } else {
                reportCoupAnalyse.setCoupNewOrderNum(DEFAULTNUM);
                reportCoupAnalyse.setCoutRepeatOrderNum(DEFAULTNUM);
                reportCoupAnalyse.setCoupPriceAmount(DEFAULTATOMIC);
                reportCoupAnalyse.setOrderOriginalPriceAmount(DEFAULTATOMIC);
            }
            reportCoupAnalyseService.addReportCoupAnalyse(reportCoupAnalyse);
            log.info("insert new data,batchId:{}", batchId);
        } catch (Exception e) {
            log.error("synReportCoupAnalyseData error:", e.getMessage(), e);
        }

    }


}
